package kr.co.casually.notification;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import kr.co.casually.MainActivity;
import kr.co.casually.R;
import kr.co.casually.adapter.ConcertDbAdapter;
import kr.co.casually.adapter.KeyWordsDbAdapter;
import kr.co.casually.adapter.MyConcertDbAdapter;
import kr.co.casually.preference.ConcertPreferences;
import kr.co.casually.types.ConcertData;
import kr.co.casually.types.KeyWord;
import kr.co.casually.util.Utils;

import org.apache.http.client.ClientProtocolException;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;
import org.kxml2.kdom.Element;
import org.kxml2.kdom.Node;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.SystemClock;
import android.preference.PreferenceManager;

public class ConcertInfoService extends Service {

	private int artCode[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
			15, 16 };
	private Notification newConcertInfoNotification;
	public static final int NOTIFICATION_ID = 1;
	private Task asyncTask = null;
	AlarmManager alarms;
	PendingIntent alarmIntent;

	private ConcertDbAdapter cocertDBAdapter;
	private MyConcertDbAdapter myConcertDBAdapter;
	private KeyWordsDbAdapter keyWordsDBAdapter;

	private ArrayList<KeyWord> keyWords;
	private ArrayList<ConcertData> notiConcertData;
	private ArrayList<ConcertData> tempConcertData; // DB 입력전 서버로 부터 정보 가져온 콘서트
													// 정보

	public String NOTIFICATION_TITLE = "새로운 서울공연정보";

	private SharedPreferences mPrefs;

	@Override
	public void onCreate() {
		super.onCreate();

		int icon = R.drawable.icon;
		long when = System.currentTimeMillis();
		mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
		newConcertInfoNotification = new Notification(icon, NOTIFICATION_TITLE,
				when);

		alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

		String ALARM_ACTION;
		ALARM_ACTION = ConcertAlarmReceiver.ACTION_REFRESH_CONCERT_ALARM;
		Intent intentToFire = new Intent(ALARM_ACTION);
		alarmIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0);
		keyWords = new ArrayList<KeyWord>();
		notiConcertData = new ArrayList<ConcertData>();
		tempConcertData = new ArrayList<ConcertData>();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		int updateFreq = 60 * 6;// 3시간
		int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
		long timeToRefresh = SystemClock.elapsedRealtime() + updateFreq * 60
				* 1000;
		alarms.setRepeating(alarmType, timeToRefresh, updateFreq * 60 * 1000,
				alarmIntent);

		refreshGetConcertInfo();
		return Service.START_NOT_STICKY;
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

	private class Task extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			keyWords.clear();
			notiConcertData.clear();
			tempConcertData.clear();
			Utils.CREATE_DB_INCREMENT = 0;
			for (int i = 0; i < artCode.length; i++) {
				 getSubjCodeArtListData(artCode[i]);

				// 최초 1회 DB 생성 프로그레스 다이얼로그
				if (!mPrefs.getBoolean(ConcertPreferences.FIRST_SERVICE, false)) {
					Utils.CREATE_DB_INCREMENT = i + 1;
					MainActivity.mProgressHandler.sendEmptyMessage(0);
				}

			}

			// 최초 1회 서비스 실행 여부 변경
			if (!mPrefs.getBoolean(ConcertPreferences.FIRST_SERVICE, false)) {
				ConcertPreferences.storeFirstService(ConcertInfoService.this,
						true);
			}

			if (tempConcertData != null && tempConcertData.size() > 0) {
				clearConcertTable(); // 콘서트 정보 DB 내용 초기화

				for (int j = 0; j < tempConcertData.size(); j++) {
					try {
						addConcert(tempConcertData.get(j)); // 새로 콘서트 정보 갱신
					} catch (ClientProtocolException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}

			}

			getMyconcertData(); // 새로운 공연정보 검색

			if (notiConcertData.size() > 0 && notiConcertData != null) {
				publishProgress(null);
			}
			return null;
		}

		@Override
		protected void onProgressUpdate(Void... values) {
			Context context = getApplicationContext();

			// 알림 설정 한경우
			if (Utils.getPreferenceNotiMsg(context)) {

				String svcName = Context.NOTIFICATION_SERVICE;

				NotificationManager notificationManager;
				notificationManager = (NotificationManager) getSystemService(svcName);

				String expandedText = notiConcertData
						.get(notiConcertData.size() - 1).getTitle().toString();
				String expandedTitle = notiConcertData
						.get(notiConcertData.size() - 1).getSubjName()
						.toString();

				Intent startActivityIntent = new Intent(
						ConcertInfoService.this, MainActivity.class);
				PendingIntent launchIntent = PendingIntent.getActivity(context,
						0, startActivityIntent, 0);

				if (Utils.getPreferenceTImeSet(context)) { // 시간설정 한 경우

				} else {

				}

				newConcertInfoNotification.flags = Notification.FLAG_AUTO_CANCEL;
				newConcertInfoNotification.setLatestEventInfo(context,
						expandedTitle, expandedText, launchIntent);
				newConcertInfoNotification.when = java.lang.System
						.currentTimeMillis();
				newConcertInfoNotification.number = notiConcertData.size();
				if (Utils.getPreferenceNotiSound(context)) { // 사운드 알림 설정한경우
					newConcertInfoNotification.defaults = Notification.DEFAULT_SOUND;
				}
				if (Utils.getPreferenceNotiVibrate(context)) { // 진동알림 설정한경우
					long[] vibration = { 1000, 1000, 500, 500, 200, 200, 200,
							200, 200, 200 };
					newConcertInfoNotification.vibrate = vibration;
				}

				notificationManager.notify(NOTIFICATION_ID,
						newConcertInfoNotification);

			}

		}

		@Override
		protected void onPostExecute(Void result) {
			stopSelf();
		}

	}

	// 공연정보 가져오는 Task 실행
	private void refreshGetConcertInfo() {
		if (asyncTask == null
				|| asyncTask.getStatus().equals(AsyncTask.Status.FINISHED)) {
			asyncTask = new Task();
			asyncTask.execute((Void[]) null);
		}
	}

	// 공연정보 클리어
	private void clearConcertTable() {
		cocertDBAdapter = new ConcertDbAdapter(this);
		cocertDBAdapter.open();

		cocertDBAdapter.clearConcertTable();

		cocertDBAdapter.close();
	}

	// 공연정보 가져오기..
	public void getSubjCodeArtListData(int code) {

		String soap_action = "http://schemas.xmlsoap.org/soap/envelope/ArtService?wsdl/searchSubjCodeArtList";

		Element h = new Element().createElement(Utils.NAMESPACE, "authInfo");
		Element username = new Element().createElement(Utils.NAMESPACE,
				"userId");
		username.addChild(Node.TEXT, "casually");
		h.addChild(Node.ELEMENT, username);

		Element authkey = new Element().createElement(Utils.NAMESPACE,
				"authKey");
		authkey.addChild(Node.TEXT,
				Utils.encodeBinary("0VENGN23I658W2A".getBytes()));
		h.addChild(Node.ELEMENT, authkey);

		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.dotNet = true;
		envelope.headerOut = new Element[1];
		envelope.headerOut[0] = h;

		SoapObject request = new SoapObject(Utils.NAMESPACE,
				"searchSubjCodeArtList");

		request.addProperty("subjCode", code);
		request.addProperty("sortItem", null);
		request.addProperty("sortStd", null);
		request.addProperty("cPage", 1);
		request.addProperty("pageSize", 100);

		envelope.setOutputSoapObject(request);
		AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(
				Utils.URL);
		androidHttpTransport.debug = true;
		try {
			androidHttpTransport.call(soap_action, envelope);

			SoapObject sobj = (SoapObject) envelope.bodyIn;

			for (int i = 0; i < sobj.getPropertyCount(); i++) {
				SoapObject obj = (SoapObject) sobj.getProperty(i);

				for (int j = 1; j < obj.getPropertyCount() - 11; j++) {

					SoapObject detail_obj = (SoapObject) obj.getProperty(j);
					ConcertData concertData = new ConcertData();
					int cultCode = Integer.valueOf(detail_obj.getProperty(
							"cultCode").toString());
					concertData.setCultCode(cultCode);
					concertData.setGenreCode(code);
					concertData.setTitle(Utils.ifNull(detail_obj
							.getProperty("title")).trim());
					concertData.setSubjName(Utils.ifNull(detail_obj
							.getProperty("subjName")).trim());
					concertData.setStartDate(Utils.ifNull(detail_obj
							.getProperty("startDate")).trim());
					concertData.setEndDate(Utils.ifNull(detail_obj
							.getProperty("endDate")).trim());
					concertData.setPlace(Utils.ifNull(detail_obj
							.getProperty("place")).trim());
					concertData.setImagepath(getArtInfoData(cultCode).trim());

					addTempConcertInfo(concertData); // 임시로 저장한다.

				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			;
		}
	}

	private void addTempConcertInfo(ConcertData concertData) {
		tempConcertData.add(concertData);
	}

	// Concert 테이블 에 새로운 공연정보 입력
	private void addConcert(ConcertData data) throws ClientProtocolException,
			IOException {

		cocertDBAdapter = new ConcertDbAdapter(this);
		cocertDBAdapter.open();
		// My concert 테이블에서 같은 cultcode 유무 확인
		if (!cocertDBAdapter.isConcert(data.getCultCode())) {

			cocertDBAdapter.createConcert(data.getCultCode(), data
					.getGenreCode(), data.getSubjName().toString(), Utils
					.changeToHtml(data.getTitle().toString()), data
					.getStartDate().toString(), data.getEndDate().toString(),
					data.getPlace().toString(), data.getImagepath().toString());
		}

		/*Log.i("test", data.getCultCode() + " / " + data.getGenreCode() + " / "
				+ data.getSubjName().toString() + " / "
				+ data.getTitle().toString() + " / "
				+ data.getStartDate().toString() + " / "
				+ data.getEndDate().toString() + " / "
				+ data.getPlace().toString() + " / "
				+ data.getImagepath().toString());
*/
		cocertDBAdapter.close();

	}

	/**
	 * 공연 상세 데이터를 가져온다.
	 * 
	 * @param method_name
	 * @param cultCode
	 *            : 공연별 상세 정보를 얻어오기 위한 cultCode
	 */
	public String getArtInfoData(int cultCode) {
		String mMainImg = "";
		String soap_action = "http://schemas.xmlsoap.org/soap/envelope/ArtService?wsdl/getArtInfo";

		Element h = new Element().createElement(Utils.NAMESPACE, "authInfo");
		Element username = new Element().createElement(Utils.NAMESPACE,
				"userId");
		username.addChild(Node.TEXT, "casually");
		h.addChild(Node.ELEMENT, username);

		Element authkey = new Element().createElement(Utils.NAMESPACE,
				"authKey");
		authkey.addChild(Node.TEXT,
				Utils.encodeBinary("0VENGN23I658W2A".getBytes()));
		h.addChild(Node.ELEMENT, authkey);

		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.dotNet = true;
		envelope.headerOut = new Element[1];
		envelope.headerOut[0] = h;

		SoapObject request = new SoapObject(Utils.NAMESPACE, "getArtInfo");

		request.addProperty("cultCode", cultCode);

		envelope.setOutputSoapObject(request);
		AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(
				Utils.URL);
		androidHttpTransport.debug = true;
		try {
			androidHttpTransport.call(soap_action, envelope);
			// System.out.println(androidHttpTransport.requestDump);

			SoapObject sobj = (SoapObject) envelope.bodyIn;
			// System.out.println(sobj.toString());
			for (int i = 0; i < sobj.getPropertyCount(); i++) {
				SoapObject obj = (SoapObject) sobj.getProperty(i);

				mMainImg = Utils.ifNull(obj.getProperty("mainImg")).trim();

//				Log.i("mMainImg-------------------------------->", mMainImg);

			}

		} catch (Exception e) {
			e.printStackTrace();
			;
		}
		return mMainImg;
	}

	private void loadSQLLiteKeyWordData() {
		keyWordsDBAdapter = new KeyWordsDbAdapter(this);
		keyWordsDBAdapter.open();

		Cursor results = keyWordsDBAdapter.fetchAllKeyWords();

		while (results.moveToNext()) {

			KeyWord keyWord = new KeyWord();
			int id = results.getInt(0);
			int genreCode = results.getInt(1);
			String genreName = results.getString(2).trim();
			String startdate = results.getString(3).trim();
			String enddate = results.getString(4).trim();
			String title = results.getString(5).trim();

			keyWord.setId(id);
			keyWord.setGenreCode(genreCode);
			keyWord.setGenreName(genreName);
			keyWord.setStartDate(startdate);
			keyWord.setEndDate(enddate);
			keyWord.setTitle(title);
			keyWords.add(keyWord);

		}

		results.close();
		keyWordsDBAdapter.close();

	}

	// 콘서트 전체 DB에서 알림설정에 등록된DB와 매칭되는 콘서트 데이터 myDB에 담기
	private void getMyconcertData() {

		loadSQLLiteKeyWordData();
		for (int i = 0; i < keyWords.size(); i++) {
			String where = " WHERE 1 ";

			if (keyWords.get(i).getGenreCode() != 0) {
				where += " AND ";
				where += " genrecode=" + keyWords.get(i).getGenreCode();
			}

			if (!Utils.isEmpty(keyWords.get(i).getTitle().trim())) {
				where += " AND ";
				where += " title like '%" + keyWords.get(i).getTitle() + "%'";
			}
			if (!Utils.isEmpty(keyWords.get(i).getStartDate())) {
				where += " AND ";
				where += " strftime('%Y-%m-%d',enddate) " + " >=  strftime('%Y-%m-%d','" + keyWords.get(i).getStartDate().trim()+"')";
			}
			if (!Utils.isEmpty(keyWords.get(i).getEndDate())) {
				where += " AND ";
				where += " strftime('%Y-%m-%d',startdate) " + " <=  strftime('%Y-%m-%d','" + keyWords.get(i).getEndDate().trim()+"')";
				
			}

			cocertDBAdapter = new ConcertDbAdapter(this);
			cocertDBAdapter.open();

//			Log.i("where", where);
			Cursor results = cocertDBAdapter.selectMyConcertList(where);

//			Log.i("where", results.getCount() + "");
			while (results.moveToNext()) {

				/*Log.i("result",
						results.getInt(1) + " - " + results.getInt(2) + " - "
								+ results.getString(3) + " - "
								+ results.getString(4) + " - "
								+ results.getString(5) + " - "
								+ results.getString(6) + " - "
								+ results.getString(7) + " - "
								+ results.getString(8));*/
				ConcertData concertData = new ConcertData();

				concertData.setCultCode(results.getInt(1));
				concertData.setGenreCode(results.getInt(2));
				concertData.setSubjName(results.getString(3));
				concertData.setTitle(results.getString(4));
				concertData.setStartDate(results.getString(5));
				concertData.setEndDate(results.getString(6));
				concertData.setPlace(results.getString(7));
				concertData.setImagepath(results.getString(8));

				myConcertDBAdapter = new MyConcertDbAdapter(this);
				myConcertDBAdapter.open();

				// My concert 테이블에서 같은 cultcode 유무 확인
				if (!myConcertDBAdapter.isMyConcert(concertData.getCultCode())) {
					myConcertDBAdapter.createMyConcert(concertData
							.getCultCode(), concertData.getGenreCode(),
							concertData.getSubjName().toString(), concertData
									.getTitle().toString(), concertData
									.getStartDate().toString(), concertData
									.getEndDate().toString(), concertData
									.getPlace().toString(), concertData
									.getImagepath().toString());

					notiConcertData.add(concertData);
				}

				myConcertDBAdapter.close();
			}
			results.close();
			cocertDBAdapter.close();

		}

	}

	// 현재 화면이 MyConcertList Activity 인경우
	private boolean foregroundAct() {
		ActivityManager am = (ActivityManager) this
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
		ComponentName topActivity = taskInfo.get(0).topActivity;
		String str = topActivity.getClassName();

		return (str.equals("kr.co.casually.MainActivity")) ? true : false;
	}

}
